<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn">防抖</button>
    <button id="btn2">节流</button>
    <script>
        // 深拷贝
        function deepClone(target) {
            let obj = Object.prototype.toString.call(target).slice(8, -1) === 'Object' ? {} : []
            for (let i in target) {
                if (target.hasOwnProperty(i)) {
                    obj[i] = typeof target[i] === 'object' ? deepClone(target[i]) : target[i]
                }
            }
            return obj
        }
        let s = {
            a: 1,
            b: {
                c: 2,
                d: [1, 2, [3, 4, 5]]
            }
        }
        // let newObj = deepClone(s)
        // console.log(newObj);


        // call apply  bind
        var a = 'window对象'
        let stu = {
            a: 'stu对象',
            b: 1
        }
        let obj = {
            a: 'obj对象',
            fn: function (b, c) {
                console.log(this.a, b, c);
            }
        }

        obj.fn(1, 2)


        Function.prototype.call = function (obj, ...args) {
            let fn = this
            obj = typeof obj === "undefined" ? window : obj
            args = args || []
            obj.fn = fn
            let res = obj.fn(...args)
            delete obj.fn
            return res
        }
        // obj.fn.call(stu, 3, 4)

        Function.prototype.apply = function (obj, arg) {
            let fn = this
            obj = typeof obj === "undefined" ? window : obj
            arg = arg || []
            obj.fn = fn
            let res = obj.fn(...arg)
            delete obj.fn
            return res
        }
        // obj.fn.apply(stu, [3, 4])

        Function.prototype.bind = function (obj, ...args) {
            return (...args2) => {
                return this.call(obj, ...args, ...args2)
            }
        }
        // obj.fn.bind(stu)(3, 4)


        // new关键字
        function Person(name, age) {
            this.name = name
            this.age = age
        }

        function Mynew(fn, ...args) {
            let obj = {}
            fn.call(obj, ...args)
            obj.__proto__ = fn.prototype
            return obj
        }
        let t = Mynew(Person, 'kobe', 18)
        // console.log(t);

        // 函数柯里化
        function add(a, b, c) {
            return a + b + c
        }

        function currying(fn) {
            return function curry(...args) {
                if (args.length < fn.length) {
                    return function (...args2) {
                        return curry(...args, ...args2)
                    }
                }
                return fn(...args)
            }
        }
        let res = currying(add)
        // console.log(res(1, 2)(3));


        // Object.create()
        let ss = {
            a: 1,
            b: 2
        }

        // tt的隐式原型等于ss的属性(tt继承了ss的属性)
        let tt = Object.create(ss)
        // console.log(tt.a, tt.b);


        // 防抖(触发多次最终只算最后一次)
        function fn() {
            console.log(111);
        }

        // 防抖函数
        function deBounce(fn, delay = 1000) {
            let timer = null
            return function (e) {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    fn.call(this, e)
                    timer = null
                }, delay)
            }
        }
        btn.onclick = deBounce(fn)

        // 节流
        function throttle(fn, delay = 1000) {
            let pre = 0;
            return function (e) {
                const now = Date.now()
                if (now - pre > delay) {
                    fn.call(this, e)
                    pre = now
                }
            }
        }
        btn2.onclick = throttle(fn)
    </script>
</body>

</html>